package com.cardone.common.converter;

import com.cardone.context.ContextHolder;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.dozer.Mapper;
import org.dozer.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 对象转换
 * Created by Administrator on 2014/9/26.
 */
@Slf4j
public class ObjectDefaultConverter implements org.dozer.ConfigurableCustomConverter {
    private String parameter;

    @Override
    public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
        if (sourceFieldValue == null) {
            if (String.class.equals(sourceClass) || Date.class.equals(sourceClass)) {
                return StringUtils.EMPTY;
            } else if (CollectionUtils.isCollection(sourceClass) || CollectionUtils.isArray(sourceClass) || CollectionUtils.isList(sourceClass) || CollectionUtils.isSet(sourceClass)) {
                return Lists.newArrayList();
            } else if (Integer.class.equals(sourceClass) || Double.class.equals(sourceClass) || Long.class.equals(sourceClass) || Float.class.equals(sourceClass) || Short.class.equals(sourceClass)) {
                return 0;
            }

            return Maps.newHashMap();
        }

        if (org.apache.commons.lang3.StringUtils.isBlank(parameter)) {
            return sourceFieldValue;
        }

        if (StringUtils.startsWithIgnoreCase(parameter, "dateFormat:")) {
            if (!(sourceFieldValue instanceof Date)) {
                return sourceFieldValue;
            }

            String dateFormat = StringUtils.remove(parameter, "dateFormat:");

            return DateFormatUtils.format((Date) sourceFieldValue, dateFormat);
        }

        String newParameter = parameter;

        com.cardone.context.function.Execution4Function execution4Function = ContextHolder.getBean(com.cardone.context.function.Execution4Function.class, newParameter);

        if (execution4Function != null) {
            return execution4Function.execution(existingDestinationFieldValue, sourceFieldValue, destinationClass, sourceClass);
        }

        if (CollectionUtils.isCollection(sourceClass)) {
            List sourceFieldList = (List) sourceFieldValue;

            if (org.apache.commons.collections.CollectionUtils.isEmpty(sourceFieldList)) {
                return Lists.newArrayList();
            }

            List destinationList = Lists.newArrayList();

            for (Object sourceField : sourceFieldList) {
                if (log.isDebugEnabled() && (sourceField != null)) {
                    log.debug("sourceField:" + sourceField.getClass().getName());
                }

                try {
                    Map<String, Object> destination = Maps.newLinkedHashMap();

                    ContextHolder.getBean(Mapper.class).map(sourceField, destination, newParameter);

                    destinationList.add(destination);
                } catch (Exception e) {
                    destinationList.add(sourceField);

                    log.error(e.getMessage(), e);
                }
            }

            return destinationList;
        }

        return ContextHolder.getBean(Mapper.class).map(sourceFieldValue, destinationClass, newParameter);
    }

    @Override
    public void setParameter(String parameter) {
        this.parameter = parameter;
    }
}
